using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Net;
using Android.Provider;
using Android.Database;
using Java.Lang;
using System.IO;
using System.IO.Compression;

namespace EightBeats
{
    public class Util
    {
        public static bool IsConnected(Context context)
        {
            var connectivityManager = (ConnectivityManager)context.GetSystemService(Context.ConnectivityService);
            var activeConnection = connectivityManager.ActiveNetworkInfo;
            return ((activeConnection != null) && activeConnection.IsConnected);
        }

        public static byte[] Compress(string str)
        {
            var bytes = Encoding.UTF8.GetBytes(str);

            using (var msi = new MemoryStream(bytes))
            using (var mso = new MemoryStream())
            {
                using (var gs = new GZipStream(mso, CompressionMode.Compress))
                {
                    CopyTo(msi, gs);
                }

                return mso.ToArray();
            }
        }

        private static void CopyTo(Stream src, Stream dest)
        {
            byte[] bytes = new byte[4096];

            int cnt;

            while ((cnt = src.Read(bytes, 0, bytes.Length)) != 0)
            {
                dest.Write(bytes, 0, cnt);
            }
        }

        public static string GetAudioRealPathFromURI(Context context, Android.Net.Uri contentURI) {

            bool isKitKat = Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Kitkat;

            // DocumentProvider
            if (isKitKat && DocumentsContract.IsDocumentUri(context, contentURI)) {
                // ExternalStorageProvider
                if (IsExternalStorageDocument(contentURI)) {
                    string docId = DocumentsContract.GetDocumentId(contentURI);
                    string[] split = docId.Split(':');
                    string type = split[0];

                    if ("primary".ToLower().Equals(type.ToLower())) {
                        return new Java.Lang.String(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath + "/" + split[1]).ToString();
                    }

                    // TODO handle non-primary volumes
                }
                // DownloadsProvider
                else if (IsDownloadsDocument(contentURI)) {

                    string id = DocumentsContract.GetDocumentId(contentURI);
                    Android.Net.Uri contentUri = ContentUris.WithAppendedId(Android.Net.Uri.Parse("content://downloads/public_downloads"), Long.ValueOf(id).LongValue());

                    return new Java.Lang.String(getDataColumn(context, contentUri, null, null)).ToString();
                }
                // MediaProvider
                else if (IsMediaDocument(contentURI)) {
                    string docId = DocumentsContract.GetDocumentId(contentURI);
                    string[] split = docId.Split(':');
                    string type = split[0];

                    Android.Net.Uri contentUri = null;
                    if ("image".Equals(type)) {
                        contentUri = MediaStore.Images.Media.ExternalContentUri;
                    } else if ("video".Equals(type)) {
                        contentUri = MediaStore.Video.Media.ExternalContentUri;
                    } else if ("audio".Equals(type)) {
                        contentUri = MediaStore.Audio.Media.ExternalContentUri;
                    }

                    string selection = "_id=?";
                    string[] selectionArgs = new string[] {
                            split[1]
                    };

                    //selection, selectionArgs

                    return new Java.Lang.String(getDataColumn(context, contentUri, selection, selectionArgs)).ToString();
                }
            }

            // MediaStore (and general)
            else if ("content".Equals(contentURI.Scheme.ToLower()))
            {
                return new Java.Lang.String(getDataColumn(context, contentURI, null, null)).ToString();
            }
            // File
            else if ("file".Equals(contentURI.Scheme.ToLower()))
            {
                return new Java.Lang.String(contentURI.Path).ToString();
            }

            return null;
        }

        /**
         * Get the value of the data column for this Uri. This is useful for
         * MediaStore Uris, and other file-based ContentProviders.
         *
         * @param context The context.
         * @param uri The Uri to query.
         * @param selection (Optional) Filter used in the query.
         * @param selectionArgs (Optional) Selection arguments used in the query.
         * @return The value of the _data column, which is typically a file path.
         */
        private static string getDataColumn(Context context, Android.Net.Uri uri, string selection, string[] selectionArgs)
        {

            ICursor cursor = null;
            string column = "_data";
            string[] projection = { column };

            try
            {
                cursor = context.ContentResolver.Query(uri, projection, selection, selectionArgs, null);
                if (cursor != null && cursor.MoveToFirst())
                {
                    int column_index = cursor.GetColumnIndexOrThrow(column);
                    return cursor.GetString(column_index);
                }
            }
            finally
            {
                if (cursor != null)
                    cursor.Close();
            }
            return null;
        }


        /**
         * @param uri The Uri to check.
         * @return Whether the Uri authority is ExternalStorageProvider.
         */
        private static bool IsExternalStorageDocument(Android.Net.Uri uri)
        {
            return "com.android.externalstorage.documents".Equals(uri.Authority);
        }

        /**
         * @param uri The Uri to check.
         * @return Whether the Uri authority is DownloadsProvider.
         */
        private static bool IsDownloadsDocument(Android.Net.Uri uri)
        {
            return "com.android.providers.downloads.documents".Equals(uri.Authority);
        }

        /**
         * @param uri The Uri to check.
         * @return Whether the Uri authority is MediaProvider.
         */
        private static bool IsMediaDocument(Android.Net.Uri uri)
        {
            return "com.android.providers.media.documents".Equals(uri.Authority);
        }

    }

}